#ifndef NS3x
#import "Thinker.h"
#import <defaults/defaults.h>
#else
#import "Thinker3.h"
#endif
#import "Fish.h"
#import "FishBrain.h"
#import <appkit/Application.h>
#import "RotImage.h"
#import <dpsclient/wraps.h>
#import <appkit/View.h>
#import <stdio.h>
#import <libc.h>
#import <math.h>
#include <sys/stat.h>

#define FISHPICTS		20	// Maximum number without recompile
#define NUMBER_OF_FRAMES	1	// Need more frames eventually

@implementation Fish

- init:sender
{
	NXRect bufferRect;
	struct stat statbuf;
	char appDirectory[MAXPATHLEN], *lastSlash, fishfile[MAXPATHLEN];
	aquarium = sender;

	sizeOfAquar.width = 700;
	sizeOfAquar.height = 700;

	srandom(currentTimeInMs());

	do {
#ifndef NS3x
		strcpy(appDirectory,NXArgv[0]);
		lastSlash = rindex(appDirectory,'/');
		strcpy((lastSlash?lastSlash+1:appDirectory),"FishFolder");

		sprintf(fishfile,"%s/fish.%d.tiff",appDirectory,random() % FISHPICTS + 1);
#else
		sprintf(fishfile,"%s/FishFolder/fish.%d.tiff",[BSThinker() moduleDirectory:"Aquarium"],(int)(random() % FISHPICTS + 1));
#endif

	} while(stat(fishfile,&statbuf) == -1); 
		
	fish = [[RotImage allocFromZone:[self zone]] initFromFile:fishfile];

	[fish getSize:&bufferRect.size];

	bufferRect.size.width /= (NUMBER_OF_FRAMES);

	WIDTH=bufferRect.size.width;
	HEIGHT=bufferRect.size.height;
	brain = [[FishBrain allocFromZone:[self zone]] init:&sizeOfAquar 
					fishSize:&bufferRect.size owner:fish];

	bufferRect.size.width += MAX_X_SPEED;
	bufferRect.size.height += MAX_Y_SPEED;

	buffer = [[NXImage alloc] initSize:&bufferRect.size];

	if ([buffer lockFocus]) {
		[self clearBuffer];	
		[buffer unlockFocus];
	}

	return self;
}

- move:listOfFish
{
	NXRect	tmpRect, myRect = {0,0,0,0};
	NXPoint	otherTo = {0,0};
	NXRect	new;
	int	x = 0;
	id	tmpObject;


	new.origin.x = [brain getXPos];
	new.origin.y = [brain getYPos];
	new.size.width = WIDTH + (MAX_X_SPEED/2);
	new.size.height = HEIGHT + (MAX_Y_SPEED/2);

	[buffer lockFocus];
	[self clearBuffer];


/*
 * The semantics that I'm using for this is that the lower indices are
 * 'behind' this fish.  The one after it in the list are in 'front' of it.
 */
	
	while((tmpObject = [listOfFish objectAt:x++]) != self) {
		tmpRect = [tmpObject getRect];
		if (NXIntersectsRect(&tmpRect,&new)) {
			otherTo.x = tmpRect.origin.x - new.origin.x + (MAX_X_SPEED/2);
			otherTo.y = tmpRect.origin.y - new.origin.y + (MAX_Y_SPEED/2);
			[tmpObject simpleDraw:&otherTo];
		}
	}

// Draw me.
	myRect.origin.x += (MAX_X_SPEED/2);
	myRect.origin.y += (MAX_Y_SPEED/2);
	[self simpleDraw:&myRect.origin];

// Here is where to draw other fish in front of this one.

	while((tmpObject = [listOfFish objectAt:x++]) != self && tmpObject != nil) {

		tmpRect = [tmpObject getRect];
		if (NXIntersectsRect(&tmpRect,&new)) {
			otherTo.x = tmpRect.origin.x - new.origin.x + (MAX_X_SPEED/2);
			otherTo.y = tmpRect.origin.y - new.origin.y + (MAX_Y_SPEED/2);
			[tmpObject simpleDraw:&otherTo];
		}
	}

	[buffer unlockFocus];

	[buffer composite:NX_COPY toPoint:&new.origin];

	old = new;
	return self;
}

- viewDidResize;
{
	NXSize imageSize;
	NXRect rect;

//	old.l = old.r = old.b = old.t = fishTo.x = fishTo.y = 0;
	[aquarium getFrame:&rect];
	sizeOfAquar = rect.size;

	[fish getSize:&imageSize];

	[brain viewDidResize:&sizeOfAquar];

	return self;
}

-(NXRect)getRect
{
	NXRect tmp;

	tmp = old;

	tmp.size.width += (2*MAX_X_SPEED) + 1;
	tmp.size.height += (2*MAX_Y_SPEED) + 1;
	return tmp;
}

-simpleDraw:(NXPoint *)point
{
	[fish composite:NX_SOVER toPoint:point];
	return self;
}

-clearBuffer
{
// Buffer must have already have the focus locked on it for this to work.
	NXRect tmp = {0,0,0,0};

	[buffer getSize:&tmp.size];
	PSsetgray(NX_BLACK);
	NXRectFill(&tmp);
	return self;
}

	
@end
